#include <stdio.h>

#include "CascadeParallel.h"
#include "Utility.h"

#define PARALLEL (2)          // 轮询
#define DEBUG_NET_DELAY (1)   // 网络延迟DEBUG_NET_DELAY ms

CascadeParallel::CascadeParallel(SOCKET* ptrConn, int indexThread, double qber)
{
    LARGE_INTEGER tc;
    QueryPerformanceFrequency(&tc);
    td.QuadPart = (LONGLONG)(tc.QuadPart / 1000.0 * DEBUG_NET_DELAY);
}

void CascadeParallel::errorCorrection()
{
    while (!flagTerminate) {   // 未结束纠错 Todo:如何结束？最后是只有接收没有发送吗？
        for (int index = 0; index < PARALLEL; index++) {
            cascadePtr = cascadeInst[index];    # Todo: cascadeInst是否变化，再次循环时cascadePtr是否变化

            // 1. 接收并比较校验子
            ReceiveData(connCascade, recvData, cascadePtr->sendBytes);

#if DEBUG_NET_DELAY != 0
            if (cascadePtr->sendBytes)   // 发送过数据
                setNetDelay(index);
#endif

            parityXOR(cascadePtr->sendBytes, cascadePtr->sendData, recvData);

            // 2. Cascade纠错
            initCascadeData();     // 补充cascadePtr数据
            cascadePtr->errorCorrection();

            // 3. 网络发送
            t1 = time()#计时
                    SendDataDaley(xxx);#重写一个发送函数，
            t2 = time() - t1;#计时，测出一个比较合适的发送数据长度
                    SendData(connCascade, cascadePtr->sendData, cascadePtr->sendBytes, 0);
            QueryPerformanceCounter(&t1[index]);
        }
    }
}

inline int CascadeParallel::ReceiveData(SOCKET conn, char* recvData, int sendBytes)
{
    int recvBytes = 0;

    while (recvBytes != sendBytes) {
        int ret = recv(conn, recvData + recvBytes, sendBytes - recvBytes, 0);   // 循环接收网络数据
        if (ret > 0)
            recvBytes = recvBytes + ret;
    };

    return recvBytes;
}

inline int CascadeParallel::SendData(SOCKET s, const char *buf, int len, int flags)
{
    //sendmutex_decoder.lock();
    int ret = 0;
    if (len)
        ret = send(s, buf, len, flags);
    //printf("Send: \tSocket = %d, \tret = %d, \tError = %d, \tsendlen = %d\n", s, ret, GetLastError(), len);
    //sendmutex_decoder.unlock();
    return ret;
}

inline void CascadeParallel::setNetDelay(int index)
{
    do {
        QueryPerformanceCounter(&t2[index]);
    } while ((t2[index].QuadPart - t1[index].QuadPart) < td.QuadPart);
}